/**
 * Copyright (c) 2024-2025 National Fundamental Software of China Co., Ltd.
 *
 * You should have find a copy of NFSChina License. If not, please contact us
 * by email <os_support@nfschina>
 *
**/

/*
    SPDX-FileCopyrightText: 1997 Patrick Dowler <dowler@morgul.fsh.uvic.ca>
    SPDX-FileCopyrightText: 2021 Cyril Rossi <cyril.rossi@enioka.com>

    SPDX-License-Identifier: GPL-2.0-or-later
*/

#pragma once

#include <QMap>
#include <QString>
#include <QWidget>
#include <QPushButton>
#include "keyboard_config.h"
#include "keyboard_dbus.h"

class QButtonGroup;
class Ui_KeyboardConfigWidget;
class KeyboardMiscSettings;
class LayoutsTableModel;
struct Rules;
class Flags;
class KeyboardConfig;
class KeyboardLayoutActionCollection;

const int DEFAULT_REPEAT_DELAY = 600;
const double DEFAULT_REPEAT_RATE = 25.0;

enum KeyBehaviour {
    AccentMenu = 0,
    RepeatKey = 1,
    DoNothing = 2,
};

const QMap<KeyBehaviour, QString> keybehaviourNames = {
    {AccentMenu, QStringLiteral("accent")},
    {RepeatKey, QStringLiteral("repeat")},
    {DoNothing, QStringLiteral("nothing")},
};

enum TriState {
    STATE_ON = 0,
    STATE_OFF = 1,
    STATE_UNCHANGED = 2,
};

class TriStateHelper
{
public:
    static void setTriState(QButtonGroup *group, TriState state);
    static TriState getTriState(const QButtonGroup *group);

    static TriState getTriState(int state)
    {
        return static_cast<TriState>(state);
    }
    static int getInt(TriState state)
    {
        return static_cast<int>(state);
    }
    static const char *getString(TriState state)
    {
        return state == STATE_ON ? "0" : state == STATE_OFF ? "1" : "2";
    }
};

class KCMiscKeyboardWidget : public QWidget
{
    Q_OBJECT
public:
    KCMiscKeyboardWidget(QWidget *parent, KeyboardMiscSettings *settings);
    ~KCMiscKeyboardWidget() override;

    void save();
    void load();
    void defaults();

    QString quickHelp() const;

    bool isSaveNeeded() const;
    bool isDefault() const;

public Q_SLOTS:
    void setDefaultIndicator(bool visible);

Q_SIGNALS:
    void changed(bool state);
    Q_SCRIPTABLE void layoutListChanged();

private Q_SLOTS:
    void changed();

    void changeVale(int num);

    void updateUiDefaultIndicator();
    void delaySliderChanged(int value);
    void delaySpinboxChanged(int value);
    void rateSliderChanged(int value);
    void rateSpinboxChanged(double value);
    void keyboardRepeatStateChanged(int selection);
    void addLayout();
    void removeLayout();
    void layoutSelectionChanged();
    void uiChanged();
    void moveUp();
    void moveDown();
    void updateXkbShortcutsButtons();
    void switchKeyboardShortcutChanged();
    void previewLayout();
    void configureXkbOptionsChanged();
    void populateWithCurrentXkbOptions();
    void scrollToGroupShortcut();
    void scrollTo3rdLevelShortcut();
    void configureLayoutsChanged();


private:
    void setRepeat(KeyBehaviour flag, int delay, double rate);
    void setDefaultIndicatorVisible(QWidget *widget, bool visible);
    void moveSelectedLayouts(int shift);
    KeyBehaviour defaultValueKeyboardRepeat() const;
    void updateLoopCount();
    QString keyboardModelFromUI() const;
    QStringList xkbOptionsFromUI() const;
    void updateXkbShortcutButton(const QString &groupName, QPushButton *button);
    QString keyboardModelFromTableView() const;
    void updateHardwareUI(const QString &model);
    void populateWithCurrentLayouts();
    QStringList getTableDataAsStringList(LayoutsTableModel *model);

    int sliderMax;
    KeyBehaviour keyboardRepeat {};
    enum TriState numlockState {};
    bool m_highlightVisible = false;

    QButtonGroup *_numlockButtonGroup;
    QButtonGroup *_keyboardRepeatButtonGroup;
    Ui_KeyboardConfigWidget &ui;
    KeyboardMiscSettings *m_settings;
    KeyboardSettingsBase *m_layoutSettings;
    LayoutsTableModel *layoutsTableModel;
    Rules *rules;
    Flags *flags;
    KeyboardConfig *keyboardConfig;
    bool uiUpdating;
    KeyboardLayoutActionCollection *actionCollection;
};
